package com.edu.zhku.wms.exception;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.edu.zhku.wms.common.CommonResult;
import com.edu.zhku.wms.common.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.LockedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.validation.ConstraintViolationException;


/**
 * @author Feng
 * @since 2021/10/29 9:18
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    public CommonResult handlerException(Exception e) {
        if (e instanceof NoHandlerFoundException) {
            log.error("【全局异常拦截】NoHandlerFoundException: 请求方法 {}, 请求路径 {}", ((NoHandlerFoundException) e).getRequestURL(), ((NoHandlerFoundException) e).getHttpMethod());
            return new CommonResult(ResultCode.REQUEST_NOT_FOUND);
        }
        if (e instanceof HttpRequestMethodNotSupportedException) {
            log.error("【全局异常拦截】HttpRequestMethodNotSupportedException: 当前请求方式 {}, 支持请求方式 {}", ((HttpRequestMethodNotSupportedException) e).getMethod(), JSONUtil.toJsonStr(((HttpRequestMethodNotSupportedException) e).getSupportedHttpMethods()));
            return new CommonResult(ResultCode.HTTP_BAD_METHOD);
        }
        if (e instanceof MethodArgumentNotValidException) {
            log.error("【全局异常拦截】MethodArgumentNotValidException", e);
            return new CommonResult(ResultCode.BAD_REQUEST.getCode(), ((MethodArgumentNotValidException) e).getBindingResult().getAllErrors().get(0).getDefaultMessage(), null);
        }
        if (e instanceof MethodArgumentTypeMismatchException) {
            log.error("【全局异常拦截】MethodArgumentTypeMismatchException: 参数名 {}, 异常信息 {}", ((MethodArgumentTypeMismatchException) e).getName(), ((MethodArgumentTypeMismatchException) e).getMessage());
            return new CommonResult(ResultCode.PARAM_NOT_MATCH);
        }
        if (e instanceof HttpMessageNotReadableException) {
            log.error("【全局异常拦截】HttpMessageNotReadableException: 错误信息 {}", ((HttpMessageNotReadableException) e).getMessage());
            return new CommonResult(ResultCode.PARAM_NOT_NULL);
        }
        if (e instanceof ConstraintViolationException) {
            log.error("【全局异常拦截】ConstraintViolationException", e);
            return new CommonResult(ResultCode.BAD_REQUEST.getCode(), CollUtil.getFirst(((ConstraintViolationException) e).getConstraintViolations()).getMessage(), null);
        }
        if (e instanceof BadCredentialsException) {
            log.error("【全局异常拦截】BadCredentialsException: 错误信息 {}", e.getMessage());
            return new CommonResult(ResultCode.USERNAME_PWD_ERROR);
        }
        if (e instanceof AccessDeniedException) {
            log.error("【全局异常拦截】AccessDeniedException: 错误信息 {}", e.getMessage());
            return CommonResult.forbidden();
        }
        if (e instanceof DisabledException) {
            log.error("【全局异常拦截】DisabledException: 错误信息 {}", e.getMessage());
            return new CommonResult(ResultCode.USER_NOT_ENABLE);
        }
        if (e instanceof LockedException) {
            log.error("【全局异常拦截】LockedException: 错误信息 {}", e.getMessage());
            return new CommonResult(ResultCode.USER_LOCKED);
        }
        log.error("【全局异常拦截】{}: 异常信息 {} ", e.getClass().getName() , e.getMessage());
        return CommonResult.error(e.getMessage());
    }
}
